using System;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using AuthService.Domain.Auth;
using AuthService.Domain.Tokens;
using AuthService.Domain.OAuth;
using AuthService.Domain.Security;

namespace AuthService.EntityFrameworkCore;

/// <summary>
/// 认证服务数据库上下文
/// </summary>
[ConnectionStringName(AuthServiceDbProperties.ConnectionStringName)]
public class AuthServiceDbContext : AbpDbContext<AuthServiceDbContext>, IAuthServiceDbContext
{
    public DbSet<AuthSession> AuthSessions { get; set; }
    public DbSet<Token> Tokens { get; set; }
    public DbSet<OAuthClient> OAuthClients { get; set; }
    public DbSet<OAuthAuthorization> OAuthAuthorizations { get; set; }
    public DbSet<SecurityEvent> SecurityEvents { get; set; }
    public DbSet<RiskAssessment> RiskAssessments { get; set; }

    public AuthServiceDbContext(DbContextOptions<AuthServiceDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.ConfigureAuthService();
    }
}

/// <summary>
/// 数据库配置扩展
/// </summary>
public static class AuthServiceDbContextModelCreatingExtensions
{
    public static void ConfigureAuthService(this ModelBuilder builder)
    {
        // 简化的实体配置，只配置实际存在的属性

        // 简化的基础配置，不包含ConfigureByConvention
        builder.Entity<AuthSession>(b =>
        {
            b.ToTable($"{AuthServiceDbProperties.DbTablePrefix}AuthSessions", AuthServiceDbProperties.DbSchema);
            b.HasKey(x => x.Id);
            b.Property(x => x.Id).ValueGeneratedOnAdd();

            b.Property(x => x.UserId).IsRequired();
            b.Property(x => x.SessionToken).HasMaxLength(512);
            b.Property(x => x.DeviceInfo).HasMaxLength(1024);
            b.Property(x => x.IpAddress).HasMaxLength(45);
            b.Property(x => x.UserAgent).HasMaxLength(1024);

            b.HasIndex(x => x.UserId);
            b.HasIndex(x => x.SessionToken);
        });

        builder.Entity<Token>(b =>
        {
            b.ToTable($"{AuthServiceDbProperties.DbTablePrefix}Tokens", AuthServiceDbProperties.DbSchema);
            b.HasKey(x => x.Id);
            b.Property(x => x.Id).ValueGeneratedOnAdd();

            b.Property(x => x.UserId).IsRequired();
            b.Property(x => x.AccessToken).HasMaxLength(2048);
            b.Property(x => x.RefreshToken).HasMaxLength(2048);
            b.Property(x => x.ClientId).HasMaxLength(256);
            b.Property(x => x.TokenType).HasMaxLength(50);

            b.HasIndex(x => x.UserId);
            b.HasIndex(x => x.AccessToken);
            b.HasIndex(x => x.RefreshToken);
        });

        builder.Entity<OAuthClient>(b =>
        {
            b.ToTable($"{AuthServiceDbProperties.DbTablePrefix}OAuthClients", AuthServiceDbProperties.DbSchema);
            b.HasKey(x => x.Id);
            b.Property(x => x.Id).ValueGeneratedOnAdd();

            b.Property(x => x.ClientId).HasMaxLength(256).IsRequired();
            b.Property(x => x.ClientSecret).HasMaxLength(512);
            b.Property(x => x.ClientName).HasMaxLength(256);
            b.Property(x => x.Description).HasMaxLength(1000);

            b.HasIndex(x => x.ClientId).IsUnique();
        });

        builder.Entity<OAuthAuthorization>(b =>
        {
            b.ToTable($"{AuthServiceDbProperties.DbTablePrefix}OAuthAuthorizations", AuthServiceDbProperties.DbSchema);
            b.HasKey(x => x.Id);
            b.Property(x => x.Id).ValueGeneratedOnAdd();

            b.Property(x => x.AuthorizationCode).HasMaxLength(512);
            b.Property(x => x.RedirectUri).HasMaxLength(2048);

            b.HasIndex(x => x.AuthorizationCode);
            b.HasIndex(x => x.UserId);
            b.HasIndex(x => x.ClientId);
        });

        builder.Entity<SecurityEvent>(b =>
        {
            b.ToTable($"{AuthServiceDbProperties.DbTablePrefix}SecurityEvents", AuthServiceDbProperties.DbSchema);
            b.HasKey(x => x.Id);
            b.Property(x => x.Id).ValueGeneratedOnAdd();

            b.Property(x => x.EventId).HasMaxLength(128);
            b.Property(x => x.EventType).HasMaxLength(100);
            b.Property(x => x.Description).HasMaxLength(1000);
            b.Property(x => x.RiskLevel).HasMaxLength(50);
            b.Property(x => x.IpAddress).HasMaxLength(45);
            b.Property(x => x.UserAgent).HasMaxLength(1024);
            b.Property(x => x.Details).HasMaxLength(2000);

            b.HasIndex(x => x.UserId);
            b.HasIndex(x => x.EventType);
            b.HasIndex(x => x.EventTime);
            b.HasIndex(x => x.RiskLevel);
        });

        builder.Entity<RiskAssessment>(b =>
        {
            b.ToTable($"{AuthServiceDbProperties.DbTablePrefix}RiskAssessments", AuthServiceDbProperties.DbSchema);
            b.HasKey(x => x.Id);
            b.Property(x => x.Id).ValueGeneratedOnAdd();

            b.Property(x => x.AssessmentId).HasMaxLength(128);
            b.Property(x => x.UserId).IsRequired();
            b.Property(x => x.ActionType).HasMaxLength(100);
            b.Property(x => x.IpAddress).HasMaxLength(45);
            b.Property(x => x.UserAgent).HasMaxLength(1024);
            b.Property(x => x.RiskScore).IsRequired();
            b.Property(x => x.RiskLevel).HasMaxLength(50);
            b.Property(x => x.RejectionReason).HasMaxLength(1000);

            b.HasIndex(x => x.UserId);
            b.HasIndex(x => x.ActionType);
            b.HasIndex(x => x.RiskLevel);
            b.HasIndex(x => x.AssessedAt);
        });
    }
}